package net.jgrm.common.db.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 实体基类
 * 所有数据库实体类的父类，包含通用字段
 *
 * @author: houyong
 * @date: 2025年09月19日
 */
@Data
public abstract class BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 主键ID
     * 使用自增策略
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 创建时间
     * 自动填充：插入时自动设置当前时间
     */
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    /**
     * 更新时间
     * 自动填充：插入和更新时自动设置当前时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

    /**
     * 创建人
     * 自动填充：插入时设置当前操作用户ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long createBy;

    /**
     * 更新人
     * 自动填充：插入和更新时设置当前操作用户ID
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateBy;

    /**
     * 逻辑删除标记
     * 0: 未删除
     * 1: 已删除
     */
    @TableLogic
    private Integer deleted;

    /**
     * 版本号
     * 用于乐观锁
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer version;

    /**
     * 租户ID
     * 用于多租户场景
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;

    /**
     * 备注信息
     */
    private String remark;

    /**
     * 扩展字段
     * 用于存储非结构化数据
     */
    private String extJson;

    /**
     * 获取实体的业务主键
     * 子类可以重写此方法返回自定义的业务主键
     *
     * @return 业务主键
     */
    public String getBusinessKey() {
        return this.id.toString();
    }

    /**
     * 设置创建人和创建时间
     * 用于手动设置创建信息
     *
     * @param userId 用户ID
     */
    public void setCreatorInfo(Long userId) {
        this.createBy = userId;
        this.updateBy = userId;
        LocalDateTime now = LocalDateTime.now();
        this.createTime = now;
        this.updateTime = now;
    }

    /**
     * 设置更新人和更新时间
     * 用于手动设置更新信息
     *
     * @param userId 用户ID
     */
    public void setUpdaterInfo(Long userId) {
        this.updateBy = userId;
        this.updateTime = LocalDateTime.now();
    }

    /**
     * 标记为删除
     * 执行逻辑删除
     */
    public void markAsDeleted() {
        this.deleted = 1;
    }

    /**
     * 标记为未删除
     * 恢复逻辑删除的记录
     */
    public void markAsNotDeleted() {
        this.deleted = 0;
    }

    /**
     * 增加版本号
     * 用于乐观锁冲突处理
     */
    public void incrementVersion() {
        this.version = this.version == null ? 1 : this.version + 1;
    }
}